//
// Created by Lenovo on 2021/12/22.
//

#include "LinkList_Queue.h"


Status InitQueue(LinkQueue *Q){

    //初始化链队列
    Q->Head=NULL;
    Q->Tail=Q->Head;
    Q->QueueSize=0;
    return OK;
}  //构造一个空栈


Status DestroyQueue(LinkQueue *Q){
    if(Q==NULL) return ERROR;
    QNode *Ptmp=Q->Head->next;
    //存储队头后的指针,从队头开始释放链队空间
    while (Q->Head!=NULL){
        free(Q->Head);
        Q->Head=Ptmp;
        Ptmp=Q->Head->next;
    }
    free(Q);
    Q=NULL;
    return OK;
}    //销毁栈Q，Q不再存在


Status ClearQueue(LinkQueue *Q){
    if(Q==NULL||Q->Head==NULL) return ERROR;
    QNode *Ptmp=Q->Head->next;
    //与销毁队列同原理，但不销毁队列本身结点
    while (Q->Head!=NULL){
        free(Q->Head);
        Q->Head=Ptmp;
        if(Q->Head!=NULL)
            Ptmp=Q->Head->next;
    }
    Q->Tail=Q->Head;
    Q->QueueSize=0;
    return OK;
}  //把Q置为空栈


Status QueueEmpty(LinkQueue Q){
    if(Q.Head==NULL)    return ERROR;
    if(Q.Head==Q.Tail)   return TRUE;
    else    return FALSE;
}   //若Q为空栈返回TRUE，否则返回FALSE


int QueueLength(LinkQueue Q){
    if(Q.Head==NULL)    return ERROR;
    return (int)(Q.QueueSize/(sizeof(QNode)));
}     //返回Q的元素个数，即栈的长度


SElemType GetHead(LinkQueue Q){
    SElemType re;
    if(Q.Tail==Q.Head) exit(ERROR);
    re=(Q.Head->data);
    return re;
}  //若栈不空，则返回栈顶元素，否则返回NULL


Status EnQueue(LinkQueue *Q,SElemType e){
    //初始化新结点空间
    QNode *newE=(QNode*) malloc(sizeof(QNode));
    if(!newE)   return ERROR;
    newE->next=NULL;
    newE->data=e;
    //队列不同情况的插入方法，队头的下一个指向队伍后方，队尾的下一个指向NULL
    if(Q->Tail==NULL){
        Q->Head=newE;
        Q->Tail=newE;
    } else{
        Q->Tail->next=newE;
        Q->Tail=newE;
    }
    Q->QueueSize+= sizeof(QNode);
    return OK;
}    //插入元素e为新的栈顶元素


SElemType DeQueue(LinkQueue *Q){
    SElemType re;
    re=Q->Head->data;
    QNode * ptmp=Q->Head->next;
    free(Q->Head);
    Q->Head=ptmp;
    return re;
}  //若栈不空，则删除栈顶元素并返回，否则返回NULL

Status QueueTraverse(LinkQueue Q,Status (*visit)(SElemType)){
    if(Q.Head==NULL)    return ERROR;
    QNode * pTmp=Q.Head;
    while (pTmp!=NULL){
        visit(pTmp->data);
        pTmp=pTmp->next;
    }
    return OK;
}     //从栈底到栈顶一次对栈中每个元素调用函数visit（），一旦visit（）失败，则返回ERROR